﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Heroius.Extension;
using Heroius.Extension.WPF;
using Heroius.Files;

namespace Ranpage
{
    public class Person : ObservableEntity
    {
        [PropertyPanel(Label = "姓名"), EntitySilo]
        public string Name { get { return _Name; } set { _Name = value; RaisePropertyChangedEvent("Name"); } } 
        string _Name = "";

        [PropertyPanel(Label = "属性"), EntitySilo]
        public ObservableCollection<Property> Properties { get; set; } = new ObservableCollection<Property>();
    }

    public class Group : ObservableEntity
    {
        [PropertyPanel(Label = "分组名"), EntitySilo]
        public string Name { get { return _Name; } set { _Name = value; RaisePropertyChangedEvent("Name"); } }
        string _Name = "";

        [PropertyPanel(Label = "属性"), EntitySilo]
        public ObservableCollection<Property> Properties { get; set; } = new ObservableCollection<Property>();

        [PropertyPanel(Label = "成员"), EntitySilo]
        public ObservableCollection<Person> Members { get; set; } = new ObservableCollection<Person>();
        [PropertyPanel(Label = "子分组"), EntitySilo]
        public ObservableCollection<Group> SubGroups { get; set; } = new ObservableCollection<Group>();

        /// <summary>
        /// 获取本分组的浅副本：名称、属性、成员、子分组均相同，但修改增加、修改集合不影响原本
        /// </summary>
        /// <returns></returns>
        public Group ShallowCopy()
        {
            var g = new Group() { Name = Name };
            foreach (var p in Properties)
            {
                g.Properties.Add(p);
            }
            foreach (var sub in SubGroups)
            {
                g.SubGroups.Add(sub);
            }
            foreach (var m in Members)
            {
                g.Members.Add(m);
            }
            return g;
        }
    }

    public class Rule: ObservableEntity
    {
        public Rule()
        {
            Command = Commands.Skip; //令UI自动设置参数框
        }

        [PropertyPanel(Label = "指令"), EntitySilo]
        public Commands Command { get { return _Command; } set { _Command = value; RaisePropertyChangedEvent("Command"); AutoChangeParams(); } }
        Commands _Command = Commands.Skip;

        [PropertyPanel(Label = "参数"), PropertyPanelCollection(Operable = false), EntitySilo]
        public ObservableCollection<Parameter> Params { get; set; } = new ObservableCollection<Parameter>();

        void AutoChangeParams()
        {
            Params.Clear();
            switch (_Command)
            {
                case Commands.Clear_Empty_Groups:
                case Commands.Clear_Marked:
                case Commands.Struct_End:
                    break;
                case Commands.Skip:
                case Commands.Move_All_Marked_To:
                case Commands.Mark_All_In:
                    Params.Add(new Parameter(1, ""));
                    break;
                case Commands.Create_Group_In:
                case Commands.Mark_Persion_In:
                case Commands.Mark_Order_In:
                case Commands.Mark_Random_In:
                case Commands.Filter_Marked_Property_Match:
                case Commands.Move_Marked_To:
                case Commands.Traversal_Order_Groups_In_As:
                case Commands.Traversal_Random_Group_In_As:
                //case Commands.If_Group_Amount_Match_In:
                //case Commands.If_Member_Amount_Match_In:
                //case Commands.If_Member_Property_Match:
                    Params.Add(new Parameter(1, ""));
                    Params.Add(new Parameter(2, ""));
                    break;
                case Commands.Create_Groups_In:
                case Commands.Select_Order_Group_In_As:
                case Commands.Select_Random_Group_In_As:
                //case Commands.If_Group_Property_Match:
                    Params.Add(new Parameter(1, ""));
                    Params.Add(new Parameter(2, ""));
                    Params.Add(new Parameter(3, ""));
                    break;
                default:
                    throw new Exception("命令不支持：参数数量不确定");
            }
        }

        /// <summary>
        /// 所有命令
        /// </summary>
        public enum Commands
        {
            /// <summary>
            /// 占位符，可附带注释(1)
            /// </summary>
            [Description("占位符，可附带注释(1)")]
            Skip,

            /// <summary>
            /// 使用(1)名称在分组(2)中创建新的子分组
            /// </summary>
            [Description("使用(1)名称在分组(2)中创建新的子分组")]
            Create_Group_In,//need param: new group name, father group name
            /// <summary>
            /// 使用(1)名称在分组(2)中创建附带连续编号的(3)个新的子分组
            /// </summary>
            [Description("使用(1)名称在分组(2)中创建附带连续编号的(3)个新的子分组")]
            Create_Groups_In,//need param: new group name, father group name, group count
            /// <summary>
            /// 移除成员和子分组均为空的分组
            /// </summary>
            [Description("移除成员和子分组均为空的分组")]
            Clear_Empty_Groups,

            /// <summary>
            /// 在分组(1)中标记成员(2)
            /// </summary>
            [Description("在分组(1)中标记成员(2)")]
            Mark_Persion_In,//need param: group name, person name
            /// <summary>
            /// 在分组(1)内顺序标记(2)个成员
            /// </summary>
            [Description("在分组(1)内顺序标记(2)个成员")]
            Mark_Order_In,//need param: group name, person amount
            /// <summary>
            /// 在分组(1)内依次标记其全部成员
            /// </summary>
            [Description("在分组(1)内标记其全部成员")]
            Mark_All_In,//need param: group name
            /// <summary>
            /// 在分组(1)内随机标记(2)个其成员
            /// </summary>
            [Description("在分组(1)内随机标记(2)个其成员")]
            Mark_Random_In,//need param: group name, person amount

            /// <summary>
            /// 对标记的成员属性(1)的值(value)进行公式(2)计算，只保留结果大于1的
            /// </summary>
            [Description("对标记的成员属性(1)的值(value)进行公式(2)计算，只保留结果大于0的")]
            Filter_Marked_Property_Match,
            /// <summary>
            /// 将标记的成员全部移动到分组(1)
            /// </summary>
            [Description("将标记的成员全部移动到分组(1)")]
            Move_All_Marked_To,//need param: group name
            /// <summary>
            /// 将指定数量(1)的成员移动到分组(2)
            /// </summary>
            [Description("将指定数量(1)的成员移动到分组(2)")]
            Move_Marked_To,//need param: group name, count
            /// <summary>
            /// 取消所有成员标记
            /// </summary>
            [Description("取消所有成员标记")]
            Clear_Marked,

            /// <summary>
            /// 结构选择：在分组(1)内顺序选择(2)个子分组，标记为(3)，并逐个执行
            /// </summary>
            [Description("结构选择：在分组(1)内顺序选择(2)个子分组，标记为(3)，并逐个执行")]
            Select_Order_Group_In_As,//need param: group name, group amount, temp name; need end
            /// <summary>
            /// 结构选择：在分组(1)内随机选择(2)个子分组，标记为(3)，并逐个执行
            /// </summary>
            [Description("结构选择：在分组(1)内随机选择(2)个子分组，标记为(3)，并逐个执行")]
            Select_Random_Group_In_As,//need param: group name, group amount, temp name; need end

            /// <summary>
            /// 结构迭代：在分组(1)内依次选择其子分组，记为(2)
            /// </summary>
            [Description("结构迭代：在分组(1)内依次选择其子分组，记为(2)")]
            Traversal_Order_Groups_In_As,//need param: group name, temp name; need end
            /// <summary>
            /// 结构迭代：在分组(1)内随机选择其子分组，记为(2)
            /// </summary>
            [Description("结构迭代：在分组(1)内随机选择其子分组，记为(2)")]
            Traversal_Random_Group_In_As,//need params: group name, temp name

            ///// <summary>
            ///// 结构判断：对提取的成员属性(1)的值(value)进行公式(2)计算，结果大于0则执行
            ///// </summary>
            //[Description("结构判断：对提取的成员属性(1)的值(value)进行公式(2)计算，结果大于0则执行")]
            //If_Member_Property_Match,//need param: prop name, expression
            ///// <summary>
            ///// 结构判断：对分组(1)的属性(2)的值(value)进行公式(3)计算，结果大于0则执行
            ///// </summary>
            //[Description("结构判断：对分组(1)的属性(2)的值(value)进行公式(3)计算，结果大于0则执行")]
            //If_Group_Property_Match,//need param: group name, prop name, expression
            ///// <summary>
            ///// 结构判断：对分组(1)中子分组的数量(count)进行公式(2)判断，结果大于0则执行
            ///// </summary>
            //[Description("结构判断：对分组(1)中子分组的数量(count)进行公式(2)判断，结果大于0则执行")]
            //If_Member_Amount_Match_In,//need param: group name, expression
            ///// <summary>
            ///// 结构判断：对分组(1)中子分组的数量(count)进行公式(2)判断，结果大于0则执行
            ///// </summary>
            //[Description("结构判断：对分组(1)中子分组的数量(count)进行公式(2)判断，结果大于0则执行")]
            //If_Group_Amount_Match_In,//need param: group name, expression

            /// <summary>
            /// 结构：结束一级
            /// </summary>
            [Description("结构：结束一级")]
            Struct_End//need begin
        }
    }

    public class RuleSet: ObservableEntity
    {
        [PropertyPanel(Label = "命令"), EntitySilo]
        public ObservableCollection<Rule> Rules { get; set; } = new ObservableCollection<Rule>();
    }

    public class Property : ObservableEntity
    {
        public Property():this("新属性", "值") { }
        public Property(string key, string value)
        {
            Key = key;
            Value = value;
        }
        [PropertyPanel(Label = "名称")]
        public string Key { get; set; } = "";
        [PropertyPanel(Label = "值")]
        public string Value { get; set; } = "";
    }

    public class Parameter: ObservableEntity
    {
        public Parameter(int key, string value)
        {
            Key = key;
            Value = value;
        }

        [PropertyPanel(Label = "#")]
        public int Key { get; internal set; } = 0;
        [PropertyPanel(Label = "值")]
        public string Value { get; set; } = "";
    }
}
